package com.jykj.modbus.equipment.service;

import com.jykj.modbus.equipment.entity.CollectInformation;
import com.jykj.modbus.equipment.entity.ReturnModBus;
import com.jykj.modbus.equipment.entity.guard.Equipment;
import com.jykj.modbus.equipment.entity.guard.EquipmentMessage;
import com.jykj.modbus.equipment.service.guard.EquipmentServiceGuard;
import com.jykj.modbus.exception.SendDataToSerialPortFailure;
import com.jykj.modbus.exception.SerialPortOutputStreamCloseFailure;
import com.jykj.modbus.system.app.HttpResponse;
import com.jykj.modbus.utils.ByteUtils;
import com.jykj.modbus.utils.MathUtils;
import com.jykj.util.config.AppConfig;
import gnu.io.SerialPort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EquipmentService extends EquipmentServiceGuard {

    /**
     * 通过条件查询设备
     * @param obj
     * @return
     */
    @Transactional
    public List<Equipment> selectEquipmentList(Equipment obj){
        return dao.selectEquipmentList(obj);
    }

    /**
     * 通过设备信息获取设备报文信息
     * @return
     */
    public List<EquipmentMessage> selectEquipmentMessage(EquipmentMessage obj){
        return dao.selectEquipmentMessage(obj);
    }

    /**
     * 串口通讯
     * @return
     */
    public HttpResponse serialPortCommunication(EquipmentMessage obj , Integer equipmentId ){
        List<CollectInformation> collectInformations = new ArrayList<CollectInformation>();
        try {
            Test test = new Test();
            //通过设备识别码获取设备信息
            Equipment equipment = new Equipment();
            equipment.setIdentificationCode(equipmentId);
            List<Equipment> equipmentList = this.dao.selectEquipmentList(equipment);
            if (equipmentList.size()>0){
                equipment = equipmentList.get(0);
            }
            obj.setSensorType(equipment.getSensorType());
            //通过该设备类型获取设备全部报文指令
            List<EquipmentMessage> message = this.dao.selectEquipmentMessage(obj);
            //最终结果Map
            Map<String, Object> getMapData = new HashMap<String, Object>();
            ReturnModBus returnModBus = new ReturnModBus();
            for (EquipmentMessage eqm : message){
                //开启串口
                returnModBus = test.openSerialPort1(null , equipment.getSensorType() , null ,
                        equipment , eqm.getResultsDigits());
                Map<String, Object> mapData = new HashMap<>();
                returnModBus.setType(eqm.getMessageType().toString());
                String data = eqm.getMessage();
                for (int i = 0 ; i < 5 ; i++){
                    SerialPortManager.sendToPort(returnModBus.getSerialport(), ByteUtils.hexStr2Byte(data));
                    mapData = returnModBus.getReturnData();
                    System.out.println(mapData);
                    if (mapData != null && mapData.size() > 0){
                        break;
                    }
                    Thread.sleep(1000);
                }
                if (mapData.size()>0){
                    //拼装数据
                    List<CollectInformation> sfList = (List<CollectInformation>)mapData.get("CollectInformation");
                    for (CollectInformation colf : sfList){
                        collectInformations.add(colf);
                    }
                }
            }
            //关闭串口
            test.closeSerialPort(null);
            return HttpResponse.success("发送接收串口数据完成!",collectInformations);
        } catch (SendDataToSerialPortFailure e) {
            e.printStackTrace();
            return HttpResponse.success("发送接收串口数据失败!",e);
        } catch (SerialPortOutputStreamCloseFailure e) {
            e.printStackTrace();
            return HttpResponse.success("发送接收串口数据失败!",e);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return HttpResponse.success("发送接收串口数据失败!",e);
        }
    }

    /**
     * 获取报文信息并处理
     * @param eqm
     * @param sensorType
     * @param instrumentNum
     * @return
     */
    public String getMessageData(EquipmentMessage eqm , String sensorType , String instrumentNum){
        String data = "";
        //如果查询设备类型为电表传感器,需要先发送查询表号指令获取电表表号
        if (sensorType.equals(AppConfig.getProperty("sensor.electricity"))){
            String dataStr = instrumentNum;
            //计算校验符结果
            String jiaoStr = MathUtils.makeCheckSum("68" + dataStr + eqm.getMessage());
            //拼装指令
            data= "FEFEFEFE68"+dataStr+eqm.getMessage()+jiaoStr+"16";
        }else {
            data = eqm.getMessage();
        }
        return data;
    }

}
